const Node = require('./node')

// 单链表类
class SinglyLinkedList {
    // 空构造器
    constructor(head = new Node(null, null)) {
        this.head = head
    }
    // 数组构造的静态方法
    static createByArray(arr) {
        let sll = new SinglyLinkedList()
        let rear = sll.head
        for (let i = 0; i <= arr.length - 1; i++) {
            rear.next = new Node(arr[i], null)
            rear = rear.next
        }
        return sll
    }
    // 返回描述字符串
    toString() {
        let str = ""
        let p = this.head
        while (p != null) {
            str += `${p.toString()}-->`
            p = p.next
        }
        return str.slice(0, str.length - 3)
    }
    // 返回链表长
    listSize() {
        let count = 0;
        let p = this.head
        while (p.next != null) {
            count++
            p = p.next
        }
        return count
    }
    // 判空
    isEmpty() {
        return this.head.next === null
    }
    // 清空链表
    clear() {
        this.head.next = null
    }
    // get方法：获取链表的第n项
    getElem(n) {
        if (n > this.listSize()) {
            throw new Error('上越界')
        }
        if (n <= 0) {
            throw new Error('下越界')
        }
        let p = this.head
        for (let i = 0; i <= n - 1; i++) {
            p = p.next
        }
        return p
    }
    // set方法：设置链表的第n项
    setElem(n, data) {
        if (data === null || data === undefined) {
            throw new Error('data值不能为null或undefined')
        }
        if (n > this.listSize()) {
            throw new Error('上越界')
        }
        if (n <= 0) {
            throw new Error('下越界')
        }
        let p = this.head
        for (let i = 0; i <= n - 1; i++) {
            p = p.next
        }
        p.data = data
    }
    // 深拷贝链表静态方法
    static deepClone(sll) {
        let newSll = new SinglyLinkedList()
        let sllp = sll.head.next
        let newsp = newSll.head
        while (sllp != null) {
            newsp.next = new Node(sllp.data, null)
            newsp = newsp.next
            sllp = sllp.next
        }
        return newSll
    }
    // 按值查找，返回节点
    searchEqual(key) {
        let p = this.head
        while (p !== null && p.data !== key) {
            p = p.next
        }
        return p
    }
    //插入，前插true，后插false，默认后插
    insert(n, data, flag = true) {
        //上界容错
        if (n > this.listSize() + 1) {
            n = this.listSize() + 1
        }
        //下界容错
        if (n <= 0) {
            n = 1
        }
        let front = this.head
        for (let i = 0; i <= n - 2; i++) {
            front = front.next
        }
        let p
        if (flag) {
            p = new Node(data, front.next)
        } else {
            p = new Node(data, front.next.next)
            front = front.next
        }
        front.next = p
    }
    //头插入
    headInsert(data) {
        this.insert(Number.MAX_VALUE*(-1), data)
    }
    //尾插入
    endInsert(data) {
        this.insert(Number.MAX_VALUE, data)
    }
    //删除
    delete(n) {
        if (n > this.listSize()) {
            throw new Error('上越界')
        }
        if (n <= 0) {
            throw new Error('下越界')
        }
        let front = this.head
        for (let i = 0; i <= n - 2; i++) {
            front = front.next
        }
        front.next = front.next.next
    }
}

module.exports = SinglyLinkedList






//测试用例
// let arr = [1, 2, 3, 4, 5]
// let sll = SinglyLinkedList.createByArray(arr)
// sll.insert(2, 100)
// console.log(sll.toString())